package bank.driver.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URLEncoder;
import java.util.HashSet;
import java.util.Set;

import bank.Account;
import bank.Bank;
import bank.InactiveException;
import bank.OverdrawException;

public class BankProxy implements Bank {
	
	private String host = "localhost";
	
	public BankProxy(){
	}
	
	protected String makeRequest(String uri) throws IOException{
		Socket s = new Socket(this.host, 8080);
		PrintWriter out = new PrintWriter(s.getOutputStream());
		out.print("GET /bank/" + uri + " HTTP/1.1\r\nHost: "+this.host+"\r\n\r\n");
		out.flush();
		BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
		StringBuffer response = new StringBuffer();
		response.append(r.readLine());
		String line = r.readLine();
		while (line != null) {
			response.append(line + "\n");
			line = r.readLine();
		}
		int pos = response.indexOf("\n\n");
		
		if (response.length()-1 > pos+2){
			return response.substring(pos+2,response.length()-1);
		}
		return "";
		
	}

	@Override
	public String createAccount(String owner) throws IOException {
		String number = this.makeRequest("createAccount?owner=" + URLEncoder.encode(owner, "UTF-8"));
		return number;
	}

	@Override
	public Account getAccount(String number) throws IOException {
		String paramseq = makeRequest("getAccount?number=" + URLEncoder.encode(number, "UTF-8"));
		if("null".equals(paramseq)){
			return null;
		}
		String[] params = paramseq.split("&");
		return new AccountProxy(params[0],params[1],this);		
	}

	@Override
	public Set<String> getAccountNumbers() throws IOException {
		String paramseq = makeRequest("getAccountNumbers");
		String[] params = paramseq.split("&");
		Set<String> nrs = new HashSet<String>();
		for (String nr : params) {
			nrs.add(nr);
		}
		return nrs;
	}

	@Override
	public boolean removeAccount(String number) throws IOException {
		String param = makeRequest("removeAccount?number=" + URLEncoder.encode(number, "UTF-8"));
		return Boolean.parseBoolean(param);
	}

	@Override
	public void transfer(Account a, Account b, double amount)
			throws IOException, IllegalArgumentException, OverdrawException,InactiveException {
		String param = makeRequest("transfer?numberA=" + URLEncoder.encode(a.getNumber(), "UTF-8") + 
								   "&numberB=" + URLEncoder.encode(b.getNumber(), "UTF-8") + 
								   "&amount=" + URLEncoder.encode(Double.toString(amount), "UTF-8"));
		if("ok".equals(param)){
			//do nothing
		} else if ("IllegalArgumentException".equals(param)){
			throw new IllegalArgumentException();
		} else if ("OverdrawException".equals(param)){
			throw new OverdrawException();
		} else if ("InactiveException".equals(param)){
			throw new InactiveException();
		}
	}

}
